package gstruct.sequential;

import gstruct.sequential.DecentLinkedList.LinkedListNode;

import java.util.AbstractSequentialList;
import java.util.ListIterator;

class LinkedListNodeList<E> extends AbstractSequentialList<LinkedListNode<E>> {

	private class NodeIterator implements ListIterator<LinkedListNode<E>> {

		private final DecentLinkedListIterator<E> baseIterator = new DecentLinkedListIterator<>(baseList);
		
		private NodeIterator(int index) {
			if (index < 0 || index >= size()) {
				throw new IndexOutOfBoundsException(index + "/" + size());
			}
			while (index-- > 0) {
				baseIterator.next();
			}
		}
		
		@Override
		public void add(LinkedListNode<E> e) {
			throw new UnsupportedOperationException();
		}

		@Override
		public boolean hasNext() {
			return baseIterator.hasNext();
		}

		@Override
		public boolean hasPrevious() {
			return baseIterator.hasPrevious();
		}

		@Override
		public LinkedListNode<E> next() {
			LinkedListNode<E> res = baseIterator.nextNode();
			baseIterator.next();
			return res;
		}

		@Override
		public int nextIndex() {
			return baseIterator.nextIndex();
		}

		@Override
		public LinkedListNode<E> previous() {
			LinkedListNode<E> res = baseIterator.previousNode();
			baseIterator.previous();
			return res;
		}

		@Override
		public int previousIndex() {
			return baseIterator.previousIndex();
		}

		@Override
		public void remove() {
			throw new UnsupportedOperationException();
		}

		@Override
		public void set(LinkedListNode<E> e) {
			throw new UnsupportedOperationException();
		}
	}
	
	private final DecentLinkedList<E> baseList;
	
	public LinkedListNodeList(DecentLinkedList<E> base) {
		baseList = base;
	}

	@Override
	public ListIterator<LinkedListNode<E>> listIterator(int index) {
		return new NodeIterator(index);
	}

	@Override
	public int size() {
		return baseList.size();
	}
}